package com.xinqi.modules.prepare.common.utils;

import cn.hutool.core.lang.UUID;
import com.alibaba.nacos.common.utils.UuidUtils;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.GetObjectRequest;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyun.oss.model.PutObjectResult;
import com.xinqi.common.base.dto.CommonFileDTO;
import com.xinqi.common.core.constant.Constants;
import com.xinqi.common.core.utils.DateUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

@Slf4j
public class AliYunOssUtil {

    private static String screekKey = "JRytVZhuB89f3ETeH1udYXznfMQK7R";
    private static String accessKey = "LTAI5tPkfy1BZy6hD94Meo9u";
    private static String endpoint = "oss-cn-hangzhou.aliyuncs.com";
    private static String bucketName = "xinqiclass";
    private static String ossUrl = "https://xinqiclass.oss-cn-hangzhou.aliyuncs.com";

    private static String COURSE = "course";

    private static final String TEMPORARY_PATH = "temp";

    /**
     * 阿里OSS文件下载到本地服务器
     */
    public static String downFile(String ossPath, String targetFolder) {
        if (Objects.equals(Constants.HTTP, ossPath)) {
            ossPath.replace(Constants.HTTPS, Constants.HTTP);
        }
        String fileName = ossPath.replace(ossUrl + "/", "");
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKey, screekKey);
        String targetFile = targetFolder + File.separator + fileName.substring(fileName.lastIndexOf("/") + 1);
        File file = new File(targetFile);
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }
        ossClient.getObject(new GetObjectRequest(bucketName, fileName), file);
        ossClient.shutdown();
        return targetFile;
    }

    /**
     * 单文件上传
     *
     * @param file
     * @param ossFolderPath
     * @return
     */
    public static String uploadToOss(MultipartFile file, String ossFolderPath) {
        String resultUrl = "";
        String uuid = UuidUtils.generateUuid().replace("-", "");
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKey, screekKey);
        try {
            //获取上传文件输入流
            InputStream inputStream = file.getInputStream();
            //获取文件名称
            String fileName = file.getOriginalFilename();
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd");
            String datePath = simpleDateFormat.format(new Date());
            //拼接
            String targetFileName = datePath + "/" + ossFolderPath + "/" + uuid + "/" + fileName;
            log.info("批量开始上传切片图片：" + targetFileName);
            ossClient.putObject(bucketName, targetFileName, inputStream);
            resultUrl = ossUrl + "/" + targetFileName;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return resultUrl;
    }


    /**
     * 本地文件上传到阿里OSS
     */
    public static List<String> uploadFile(List<String> filePaths, String ossFolderPath) {
        List<String> ossUrls = new ArrayList<>();
        String uuid = UuidUtils.generateUuid().replace("-", "");
        try {
            if (filePaths != null && filePaths.size() > 0) {
                OSS ossClient = new OSSClientBuilder().build(endpoint, accessKey, screekKey);
                for (String path : filePaths) {
                    File file = new File(path);
                    //获取上传文件输入流
                    InputStream inputStream = new FileInputStream(path);
                    //获取文件名称
                    String fileName = file.getName();
                    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd");
                    String datePath = simpleDateFormat.format(new Date());
                    //拼接
                    String targetFileName = datePath + "/" + ossFolderPath + "/" + uuid + "/" + fileName;
                    ossClient.putObject(bucketName, targetFileName, inputStream);
                    ossUrls.add(ossUrl + "/" + targetFileName);
                }
            }
        } catch (Exception e) {
            return null;
        }
        return ossUrls;
    }


    public static CommonFileDTO uploadFileStream(String filename, Integer type, InputStream inputStream) {
        CommonFileDTO commonFile = new CommonFileDTO();
        BufferedImage bufferedImage;

        if (filename == null || StringUtils.isEmpty(filename)) {
            filename = COURSE + "/" + UUID.randomUUID() + "-" + DateUtils.dateTimeNow() + ".png";
        }
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKey, screekKey);
        try {
            commonFile.setSize((long) inputStream.available());
            bufferedImage = ImageIO.read(inputStream);

            saveTemplate(bufferedImage, filename);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        InputStream ins;
        try {
            ins = Files.newInputStream(Paths.get("/" + TEMPORARY_PATH + "/" + filename));
            // 创建PutObjectRequest对象。
            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, filename, ins);
            // 设置该属性可以返回response。如果不设置，则返回的response为空。
            putObjectRequest.setProcess("true");
            // 创建PutObject请求。
            PutObjectResult result = ossClient.putObject(putObjectRequest);
            // 宽度
            commonFile.setWidth(Math.toIntExact(bufferedImage.getWidth()));
            // 高度
            commonFile.setHeight(Math.toIntExact(bufferedImage.getHeight()));
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            ossClient.shutdown();
            //删除临时文件
            deleteTemporaryFile("/" + TEMPORARY_PATH + "/" + filename);
        }

        commonFile.setFilename(filename);
        commonFile.setFileUrl(ossUrl + "/" + filename);
        commonFile.setType(type);
        commonFile.setOssFilename(filename);
        commonFile.setUrl(ossUrl + "/" + filename);
        return commonFile;
    }

    public static CommonFileDTO uploadExamFileStream(String filename, Integer type, InputStream inputStream) {
        CommonFileDTO commonFile = new CommonFileDTO();
        BufferedImage bufferedImage;

        if (filename == null || StringUtils.isEmpty(filename)) {
            filename = COURSE + "/" + UUID.randomUUID() + "-" + DateUtils.dateTimeNow() + ".png";
        }
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKey, screekKey);
        try {
            commonFile.setSize((long) inputStream.available());
            bufferedImage = ImageIO.read(inputStream);

            saveTemplate(bufferedImage, filename);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        InputStream ins;
        try {
            ins = Files.newInputStream(Paths.get("/" + TEMPORARY_PATH + "/" + filename));
            // 创建PutObjectRequest对象。
            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, filename, ins);
            // 设置该属性可以返回response。如果不设置，则返回的response为空。
            putObjectRequest.setProcess("true");
            // 创建PutObject请求。
            PutObjectResult result = ossClient.putObject(putObjectRequest);
            // 宽度
            commonFile.setWidth(Math.toIntExact(Math.toIntExact(bufferedImage.getWidth())));
            // 高度
            commonFile.setHeight(Math.toIntExact(Math.toIntExact(bufferedImage.getHeight())));
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            ossClient.shutdown();
            //删除临时文件
            deleteTemporaryFile("/" + TEMPORARY_PATH + "/" + filename);
        }

        commonFile.setFilename(filename);
        commonFile.setFileUrl(ossUrl + "/" + filename);
        commonFile.setType(type);
        commonFile.setOssFilename(filename);
        commonFile.setUrl(ossUrl + "/" + filename);
        return commonFile;
    }

    /**
     * 临时文件
     *
     * @param bufferedImage
     * @param bufferedImage
     * @param filename
     * @throws IOException
     */
    private static void saveTemplate(BufferedImage bufferedImage, String filename) throws IOException {
        File upload = new File("/" + TEMPORARY_PATH + "/", filename);
        if (!upload.exists()) {
            upload.mkdirs();
        }
        ImageIO.write(bufferedImage, "png", upload);
    }

    private static void deleteTemporaryFile(String path) {
        File fileDelete = new File(path);
        fileDelete.delete();
    }

}
